package com.riche.usercenter.service;

import com.riche.usercenter.model.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @ClassName: InsertUsers
 * @Description: 线程池插入用户信息
 * @Author: Gaoruiqi
 * @Date: 2025-09-03 22:08
 * @Version: 1.0
 **/
@SpringBootTest
public class InsertUsers {

    @Resource
    private UserService userService;

    // CPU 密集型：分配的核心线程数 = CPU核数 - 1
    // IO 密集型：分配的核心线程数可以大于 CPU 核数
    private ExecutorService executorService = new ThreadPoolExecutor(
            20,
            100,
            1000,
            TimeUnit.MINUTES,
            new ArrayBlockingQueue<>(1000),
            new ThreadPoolExecutor.DiscardPolicy()
    );

    @Test
    public void doInsertUsers() {
        // todo spring的小插件，测量时间
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        final int INSERT_NUM = 100000;
        int batchSize = 10000;
        int j = 0;
        // 定义一个任务数组：
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            List<User> userList = new ArrayList<>();
            while (true) {
                j++;
                User user = new User();
                user.setUsername("gaoruiqimoke");
                user.setUserAccount("fakeruiqi");
                user.setAvatarUrl("https://b0.bdstatic.com/ugc/9TZTnf7wpJBYaWYjVslJCA1a6b5079eefbedc2e4d51e981b7e6c25.jpg");
                user.setGender(0);
                user.setUserPassword("12345678");
                user.setPhone("13135467897");
                user.setEmail("234443634@qq.com");
                user.setUserStatus(0);
                user.setUserRole(0);
                user.setIsDelete(0);
                user.setTags("[\"男\", \"java\"]");
                user.setProfile("这个是我的简介哦");
                userList.add(user);
                if (j % 10000 == 0) {
                    break;
                }
            }
            // todo 新建一个异步的任务：批量插入，现在这个操作就是异步的了,里面可以指定一个线程池，默认是使用ForkJoinPool.commonPool()
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                System.out.println("ThreadName:" + Thread.currentThread().getName());
                userService.saveBatch(userList, batchSize);
            }, executorService);
            // 这里添加到任务列表中，相当于拿到了10个异步任务
            futureList.add(future);
        }
        // todo 等待所有任务执行完成
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }
}
